﻿// ===============================================================================
//  Copyright © ymind.net. All rights reserved .
//  官方网站：http://ymind.net/
//  版权所有：彦铭工作室 老陈出品
// ===============================================================================

using System.Collections;
using System.Linq;
using Lcsoft.UrlRewriter.Conditions;

namespace Lcsoft.UrlRewriter.Actions
{
	/// <summary>
	/// 提供条件匹配功能的地址重写动作。
	/// </summary>
	public class ConditionalAction : IRewriteAction, IRewriteCondition
	{
		/// <summary>
		/// 初始化 <see cref="ConditionalAction"/> 类的新实例。
		/// </summary>
		public ConditionalAction()
		{
			this.Actions = new ArrayList();
			this.Conditions = new ArrayList();
		}

		/// <summary>
		/// 获取地址重写先决条件的集合。
		/// </summary>
		public IList Conditions { get; private set; }

		/// <summary>
		/// 获取地址重写规则的集合。
		/// </summary>
		public IList Actions { get; private set; }

		#region IRewriteAction Members

		/// <summary>
		/// 执行动作。
		/// </summary>
		/// <param name="context"><see cref="RewriteContext"/> 对象的实例。</param>
		/// <returns>返回 <see cref="RewriteProcessing"/> 枚举值之一。</returns>
		public virtual RewriteProcessing Execute(RewriteContext context)
		{
			foreach (var action in this.Actions)
			{
				var condition = action as IRewriteCondition;

				if (condition != null && !condition.IsMatch(context)) continue;

				var rewriteAction = action as IRewriteAction;

				if (rewriteAction == null) continue;

				var processing = rewriteAction.Execute(context);

				if (processing == RewriteProcessing.ContinueProcessing) continue;

				return processing;
			}

			return RewriteProcessing.ContinueProcessing;
		}

		#endregion

		#region IRewriteCondition Members

		/// <summary>
		/// 判断条件是否满足。
		/// </summary>
		/// <param name="context"><see cref="RewriteContext"/> 对象的实例。</param>
		/// <returns>如果条件满足则返回 true，否则返回 false。</returns>
		public virtual bool IsMatch(RewriteContext context) { return this.Conditions.Cast<IRewriteCondition>().All(condition => condition.IsMatch(context)); }

		#endregion
	}
}
